package com.njtoyo.taxi.admin.service.business.geo.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.njtoyo.taxi.admin.cache.PrimaryCachePutter;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.library.common.util.CopyUtil;
import com.njtoyo.taxi.admin.logic.geo.CustomerRegionAreaLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoCustomerRegion;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoCustomerRegionArea;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoCustomerRegionAreaMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoCustomerRegionMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.geo.AllListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.geo.RegionListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.AdminUserIdentityPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.canton.RegionAreaCreateWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.canton.RegionCreateWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.canton.RegionQueryWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.canton.RegionUpdateWrapper;
import com.njtoyo.taxi.admin.service.business.geo.GeoCustomerRegionService;
import com.taxi.entity.common.RestResult;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.njtoyo.taxi.entity.backend.Enum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Component
@DS(Const.PRIMARY_DS)
public class GeoCustomerRegionServiceImpl implements GeoCustomerRegionService {
    @Autowired
    private GeoCustomerRegionMapper geoCustomerRegionMapper;

    @Autowired
    private GeoCustomerRegionAreaMapper geoCustomerRegionAreaMapper;

    @Autowired
    private CustomerRegionAreaLogic customerRegionAreaLogic;
    @Autowired
    private PrimaryCachePutter primaryCachePutter;


    @Override
    public RestResult<List<AllListPresenter>> getAll(AdminUser adminUser) {
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter) adminUser.getIdentity();

        List<GeoCustomerRegion> list = new LambdaQueryChainWrapper<>(geoCustomerRegionMapper)
                .in(!adminUser.getAccountType().equals(Enum.AccountType.platform), GeoCustomerRegion::getId, identity.getCustomerRegionIds())
                .select(GeoCustomerRegion::getId, GeoCustomerRegion::getName)
                .list();

        List<AllListPresenter> res = CopyUtil.copyList(list, AllListPresenter.class);

        return RestResult.success(res);
    }

    @Override
    @Transactional
    public RestResult create(RegionCreateWrapper wrapper) {
        // 校验是否已经存在area_id
        Boolean checkAreaIdsExist = this.checkAreaIdsExist(null, wrapper.getAreaIds());
        if (checkAreaIdsExist) {
            return RestResult.failed("地区已被行政区引用，请检查所选择的地区");
        }

        // geo_customer_region
        GeoCustomerRegion region = new GeoCustomerRegion();
        region.setName(wrapper.getName());
        geoCustomerRegionMapper.insert(region);

        Long regionId = region.getId();

        // geo_customer_region_area
        List<RegionAreaCreateWrapper> list = new ArrayList<>();
        for (Long areaId : wrapper.getAreaIds()) {
            RegionAreaCreateWrapper item = new RegionAreaCreateWrapper();
            item.setRegionId(regionId);
            item.setAreaId(areaId);
            list.add(item);
        }

        geoCustomerRegionAreaMapper.createBatch(list);
        primaryCachePutter.deleteDriverRegion();
        primaryCachePutter.deleteAllArea();

        return RestResult.success();
    }

    @Override
    public RestResult<IPage<RegionListPresenter>> getList(RegionQueryWrapper wrapper) {
        IPage<RegionListPresenter> res = geoCustomerRegionMapper.getListByPage(wrapper);

        List<Long> cantonIds = res.getRecords().stream().map(RegionListPresenter::getId).collect(Collectors.toList());
        if (!cantonIds.isEmpty()) {
            List<AllListPresenter> areaList = geoCustomerRegionMapper.getListByCantonIds(cantonIds);
            for (RegionListPresenter region : res.getRecords()) {
                List<AllListPresenter> itemAreaList = new ArrayList<>();
                for (AllListPresenter area : areaList) {
                    if (region.getId().equals(area.getRegionId())) {
                        itemAreaList.add(area);
                    }
                }
                Boolean isClose = primaryCachePutter.getSimpleCallIsClose(region.getId());
                region.setIsClose(isClose);
                region.setAreaList(itemAreaList);
            }
        }

        return RestResult.success(res);
    }

    @Override
    public RestResult<Boolean> update(Long id, RegionUpdateWrapper wrapper) {
        // 校验是否已经存在area_id
        Boolean checkAreaIdsExist = this.checkAreaIdsExist(id, wrapper.getAreaIds());
        if (checkAreaIdsExist) {
            return RestResult.failed("地区已被行政区引用，请检查所选择的地区");
        }

        // geo_driver_region
        new LambdaUpdateChainWrapper<>(geoCustomerRegionMapper)
                .eq(GeoCustomerRegion::getId, id)
                .set(Objects.nonNull(wrapper.getName()), GeoCustomerRegion::getName, wrapper.getName())
                .update();

        // geo_driver_region_area
        if (!wrapper.getAreaIds().isEmpty()) {
            // 删除原有areaIds
            QueryWrapper<GeoCustomerRegionArea> deleteArea = new QueryWrapper<>();
            deleteArea.eq("customer_region_id", id);
            geoCustomerRegionAreaMapper.delete(deleteArea);

            // 写入新的areaIds
            customerRegionAreaLogic.createInsert(id, wrapper.getAreaIds());
            primaryCachePutter.deleteDriverRegion();
            primaryCachePutter.deleteAllArea();
        }

        return RestResult.success();
    }

    // 校验是否已经存在area_id
    private Boolean checkAreaIdsExist(Long regionId, List<Long> areaIds) {
        if (areaIds.isEmpty()) {
            return true;
        }

        Integer areaCheckCount = new LambdaQueryChainWrapper<>(geoCustomerRegionAreaMapper)
                .in(GeoCustomerRegionArea::getAreaId, areaIds)
                .ne(Objects.nonNull(regionId), GeoCustomerRegionArea::getCustomerRegionId, regionId)
                .count();

        return areaCheckCount > 0;
    }


    @Override
    public RestResult setCustomerRegionClose(Long id, Boolean isClose) {
        if(isClose){
            primaryCachePutter.setSimpleCallIsClose(id, true);
        }else {
            primaryCachePutter.setSimpleCallIsClose(id, false);
        }
        return RestResult.success();
    }

}
